import { App, ConfigProvider, Select, Tree, TreeDataNode, TreeProps } from 'antd';
import { useCatch } from '@/hooks';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useQuery } from '@tanstack/react-query';
import RealTimeMonitoringServices from '@/api/services/realTimeMonitoringServices.ts';
import { createStyles } from 'antd-style';
import {
  TreeCarIcon,
  TreeCompanyIcon,
  TreeNodeSwitchCloseIcon,
  TreeNodeSwitchOpenIcon,
} from '@ycx/ui';
import {
  useAddedMarkerList,
  useSetAddMarkerList,
  useSetRemoveMarkerList,
  useSetSingleAddMarker,
  useSetVideoCarNo,
  useSingleAddMarker,
  useVideoCarNo,
} from '@/store/realTimeMonitoringStore.ts';
import { CarInfo } from '#/entity.ts';
import { without } from 'lodash-es';
import { Key } from 'antd/es/table/interface';

interface TreeNodeData extends TreeDataNode {
  data?: CarInfo;
}

const useStyle = createStyles(({ css }) => {
  const carStatusTitle = css`
    padding-left: 4px;
    font-size: 12px;
    font-style: normal;
    font-weight: 400;
    line-height: 18px;
  `;
  return {
    treeWrapper: css`
      & .ant-tree-treenode {
        width: 100% !important;
        //padding-top: 8px !important;
        //padding-bottom: 8px !important;
      }

      & span.ant-tree-node-content-wrapper {
        display: flex;
        align-items: center;
        flex: 1;

        &.ant-tree-node-content-wrapper-normal {
          margin-left: 4px;
          //padding-left: 8px;
        }
      }

      & .ant-tree-switcher {
        display: flex;
        align-items: center;

        &::before {
          top: 8px;
        }
      }

      & .ant-tree-indent-unit {
        width: 30px;
      }

      & .ant-tree-icon__customize {
        margin-right: 14px;
      }

      & .ant-tree-treenode-motion {
        width: 100%;
      }

      & .ant-tree-checkbox {
        order: 1;
        margin-inline-start: 8px;
        margin-top: 12px;
        //transition: none !important;
        //margin-inline-end: 0;
      }

      & .ant-tree-switcher {
        display: flex;
      }
    `,
    carStatusDriving: css`
      ${carStatusTitle};
      color: var(--ycx-primary-color);
    `,
    carStatusOffline: css`
      ${carStatusTitle};
      color: var(--ycx-font-color-l2);
    `,
  };
});

const options = [
  { label: '所有状态', value: -1 },
  { label: '行驶中', value: 1 },
  { label: '离线', value: 0 },
];

const CarTree = () => {
  const { message } = App.useApp();
  const catchFn = useCatch();
  const { styles } = useStyle();

  const [status, setStatus] = useState(-1);
  const [treeData, setTreeData] = useState<TreeDataNode[]>();
  const [checkedKeys, setCheckedKeys] = useState<Key[]>([]);

  const videoCarNo = useVideoCarNo();
  const setVideoCarNo = useSetVideoCarNo();

  const setAddMarkerList = useSetAddMarkerList();
  const setRemoveMarkerList = useSetRemoveMarkerList();
  const singleAddMarker = useSingleAddMarker();
  const setSingleAddMarker = useSetSingleAddMarker();
  const addedMarkerList = useAddedMarkerList();

  // fetch data
  const { data } = useQuery({
    queryKey: ['companyCarTree', status],
    queryFn: () =>
      catchFn(() =>
        RealTimeMonitoringServices.getCompanyCarTree({
          carStatus: status > -1 ? status : undefined,
        }),
      ),
    select: ({ data }) => data,
    staleTime: 0,
  });

  const clickTimerRef = useRef<number>();

  // tree node click
  const handleClick = useCallback(
    (car: CarInfo) => {
      if (!window.AMap) {
        message.warning('请等待地图加载完成后再操作');
        return;
      }
      if (clickTimerRef.current) {
        clearTimeout(clickTimerRef.current);
        clickTimerRef.current = undefined;
        return;
      }
      clickTimerRef.current = setTimeout(() => {
        clickTimerRef.current = undefined;
        if (car.carStatus === 0) {
          message.warning('车辆离线，无法获取相关信息');
          return;
        }
        setSingleAddMarker(car);
        setCheckedKeys(Array.from(new Set([...checkedKeys, car.carNo])));
      }, 300);
    },
    [checkedKeys],
  );

  // build tree
  useEffect(() => {
    const td = data?.map<TreeNodeData>((item) => {
      return {
        title: <div style={{ padding: '8px 0' }}>{item.companyName}</div>,
        key: `company_${item.id}`,
        icon: <TreeCompanyIcon style={{ color: 'var(--ycx-font-color-l3)', fontSize: '24px' }} />,
        children: item.carList.map((car) => ({
          title: (
            <span
              onDoubleClick={() => {
                setVideoCarNo(car);
                setCheckedKeys(Array.from(new Set([...checkedKeys, car.carNo])));
              }}
              onClick={() => handleClick(car)}
              style={{ display: 'inline-block', width: '100%', padding: '8px' }}
            >
              {car.carNo}
              <span
                className={car.carStatus === 1 ? styles.carStatusDriving : styles.carStatusOffline}
              >
                {options.find((item) => item.value === car.carStatus)?.label}
              </span>
            </span>
          ),
          key: car.carNo,
          data: car,
        })),
      };
    });

    setTreeData(td);
  }, [data, setVideoCarNo, styles.carStatusDriving, styles.carStatusOffline, handleClick]);

  // tree node check
  const handleCheck: TreeProps['onCheck'] = (checkedKeys, info) => {
    if (!window.AMap) {
      message.warning('请等待地图加载完成后再操作');
      return;
    }
    const { checked, checkedNodes, node } = info;
    const carList = checkedNodes
      .filter((item) => !item.children)
      .map<CarInfo>((item: TreeNodeData) => item.data!)
      .filter((i) => i.carTrackPartPo);

    if (checked) {
      // put some shit to addList or singleAddList
      if ((node.key as string).startsWith('company_')) {
        const checkedCarNoList = carList.map((item) => item.carNo);
        const needAddList = without(checkedCarNoList, ...addedMarkerList);
        setAddMarkerList(carList.filter((i) => needAddList.includes(i.carNo)));
      } else {
        setSingleAddMarker(carList[0]);
      }
    } else {
      if ((node.key as string).startsWith('company_')) {
        setRemoveMarkerList(carList.length ? carList.map((i) => i.carNo) : addedMarkerList);
        setSingleAddMarker();
      } else {
        setRemoveMarkerList([node.key]);
        if (node.key === singleAddMarker?.carNo) setSingleAddMarker();
      }
    }
    setCheckedKeys(checkedKeys as Key[]);
  };

  return (
    <>
      <div className="flex-1 px-6 pt-4">
        <ConfigProvider theme={{ components: { Select: { fontSize: 12, optionFontSize: 12 } } }}>
          <Select
            variant="borderless"
            placeholder="车辆状态"
            options={options}
            value={status}
            onChange={(value) => setStatus(value)}
            style={{ width: '90px' }}
            size="small"
            className="mb-4"
          />
        </ConfigProvider>
        <ConfigProvider
          theme={{
            components: {
              Tree: {
                colorBgContainer: 'transparent',
                colorText: 'var(--ycx-font-color-l2)',
                nodeHoverBg: '#4C68FF14',
                nodeSelectedBg: 'var(--ycx-primary-color-pale)',
              },
            },
          }}
        >
          <Tree
            selectable
            checkable
            showIcon
            showLine={{
              showLeafIcon: (props) => (
                <TreeCarIcon
                  style={{
                    fontSize: '24px',
                    color:
                      props.data.data.carStatus === 1
                        ? 'var(--ycx-primary-color)'
                        : 'var(--ycx-font-color-l3)',
                  }}
                />
              ),
            }}
            treeData={treeData}
            className={styles.treeWrapper}
            switcherIcon={(props) =>
              props.expanded ? (
                <TreeNodeSwitchCloseIcon
                  style={{ color: 'var(--ycx-font-color-l3)', fontSize: '24px' }}
                />
              ) : (
                <TreeNodeSwitchOpenIcon
                  style={{ color: 'var(--ycx-font-color-l3)', fontSize: '24px' }}
                />
              )
            }
            checkedKeys={checkedKeys}
            onCheck={handleCheck}
            selectedKeys={
              videoCarNo ? [videoCarNo.carNo] : singleAddMarker ? [singleAddMarker.carNo] : []
            }
          />
        </ConfigProvider>
      </div>
    </>
  );
};

export default CarTree;
